<template>
  <div class="app-container">
    <!-- 顶部导航 -->
    <div class="chat-header">
      <el-breadcrumb separator="/" class="breadcrumb">
        <el-breadcrumb-item>客服管理</el-breadcrumb-item>
        <el-breadcrumb-item>会话聊天</el-breadcrumb-item>
      </el-breadcrumb>
      <el-button 
        type="primary" 
        size="mini" 
        @click="handleEndSession"
        v-if="sessionStatus === 0"
        icon="el-icon-circle-close"
      >
        结束会话
      </el-button>
    </div>

    <!-- 会话状态提示 -->
    <div class="session-status">
      <span>用户：{{ userName || '未知用户' }}</span>
      <span class="split">|</span>
      <span :class="sessionStatus === 0 ? 'text-success' : 'text-info'">
        {{ sessionStatus === 0 ? '会话活跃' : '会话已结束' }}
      </span>
      <span class="split">|</span>
      <span :class="socketConnected ? 'text-success' : 'text-danger'">
        {{ socketConnected ? '连接正常' : '连接断开' }}
      </span>
    </div>

    <!-- 聊天内容区域 -->
    <div class="chat-content" ref="chatContentRef">
      <!-- 无消息/加载提示 -->
      <div class="empty-tip" v-if="messageList.length === 0 && !loading">
        <i class="fa fa-comments-o"></i>
        <p>暂无聊天记录</p>
      </div>
      <div class="loading-tip" v-if="loading">
        <el-loading-spinner></el-loading-spinner>
        <span>加载中...</span>
      </div>

      <!-- 消息列表 -->
      <div v-for="(msg, index) in messageList" :key="index" class="message-item">
        <!-- 客服消息 -->
        <div class="customer-msg" v-if="msg.customerMessageSenderType === 3">
          <el-avatar :src="customerAvatar" size="small"></el-avatar>
          <div class="msg-bubble customer-bubble">
            <p v-if="msg.customerMessageType === 1">{{ msg.customerMessageContent }}</p>
            <el-image 
              v-if="msg.customerMessageType === 2"
              :src="msg.customerMessageImageUrl" 
              class="msg-image"
              preview-src-list="[msg.customerMessageImageUrl]"
            ></el-image>
            <span class="msg-time">{{ formatTime(msg.customerMessageCreateTime) }}</span>
          </div>
        </div>

        <!-- 用户消息 -->
        <div class="user-msg" v-if="msg.customerMessageSenderType === 2">
          <div class="msg-bubble user-bubble">
            <p v-if="msg.customerMessageType === 1">{{ msg.customerMessageContent }}</p>
            <el-image 
              v-if="msg.customerMessageType === 2"
              :src="msg.customerMessageImageUrl" 
              class="msg-image"
              preview-src-list="[msg.customerMessageImageUrl]"
            ></el-image>
            <span class="msg-time">{{ formatTime(msg.customerMessageCreateTime) }}</span>
          </div>
          <el-avatar :src="userAvatar" size="small"></el-avatar>
        </div>
      </div>
    </div>

    <!-- 输入区域（完全移除手动Token） -->
    <div class="chat-footer" v-if="sessionStatus === 0">
      <!-- 图片上传：无需手动加Authorization头 -->
      <el-upload
        class="upload-btn"
        action="/dev-api/chat/upload/image"
        :data="{ sessionId: sessionId }" 
        :on-success="handleImageUpload"
        :show-file-list="false"
        accept="image/*"
        :disabled="!socketConnected"
      >
        <el-button icon="el-icon-picture-outline" size="mini"></el-button>
      </el-upload>

      <!-- 输入框+发送 -->
      <el-input
        v-model="messageContent"
        placeholder="输入消息（按Enter发送）..."
        @keyup.enter.native="sendMsg"
        :disabled="!socketConnected"
        clearable
      ></el-input>
      <el-button 
        type="primary" 
        @click="sendMsg"
        :disabled="!messageContent.trim() || !socketConnected"
        size="mini"
      >
        发送
      </el-button>
    </div>
  </div>
</template>

<script>
// 只引入必要工具类，无需手动处理Token
import { parseTime } from "@/utils/ruoyi";
import request from "@/utils/request";

export default {
  name: "CustomerServiceChat",
  data() {
    return {
      // 核心业务参数
      sessionId: this.$route.query.sessionId || "",
      userId: this.$route.query.userId || "",
      userName: "",
      userAvatar: "/img/user2-160x160.jpg", // 若依默认头像
      customerAvatar: "/img/profile.jpg",
      sessionStatus: 0, // 0-活跃 1-结束
      
      // 聊天数据
      messageList: [],
      messageContent: "",
      loading: false,
      socketConnected: false,
      
      // WebSocket配置（Token通过拦截器处理，此处无需手动传）
      socket: null,
      reconnectTimer: null,
      baseUrl: process.env.VUE_APP_BASE_API
    };
  },
  created() {
    // 若依拦截器自动处理登录校验，此处简化
    this.getSessionInfo();
    this.loadHistoryMsg();
    this.initWs();
  },
  beforeDestroy() {
    this.socket?.close();
    clearTimeout(this.reconnectTimer);
  },
  methods: {
    /** 1. 获取会话信息：请求拦截器自动加Token */
    getSessionInfo() {
      if (!this.sessionId) return;
      request({
        url: "/chat/session/info",
        params: { sessionId: this.sessionId } // 只传业务参数
      }).then(res => {
        if (res.code === 200) {
          this.userName = res.data.userName || "未知用户";
          this.userAvatar = res.data.userAvatar || this.userAvatar;
          this.sessionStatus = res.data.sessionStatus;
        }
      });
    },

    /** 2. 初始化WebSocket：Token通过若依拦截器处理（后端需兼容） */
    initWs() {
      if (!this.sessionId || this.sessionStatus === 1) return;
      
      const wsProtocol = window.location.protocol === "https:" ? "wss:" : "ws:";
      const wsBaseUrl = this.baseUrl.includes("dev-api") 
        ? window.location.host + "/dev-api" 
        : this.baseUrl.replace(/^https?:\/\//, "");
      // WebSocket Token：若依拦截器若不处理WS，需后端支持从Cookie/Header自动获取（此处简化）
      const wsUrl = `${wsProtocol}//${wsBaseUrl}/chat/ws?sessionId=${this.sessionId}`;

      this.socket = new WebSocket(wsUrl);
      this.socket.onopen = () => {
        this.socketConnected = true;
        this.$message.success("聊天连接已建立");
      };
      this.socket.onmessage = (e) => {
        const msg = JSON.parse(e.data);
        !this.messageList.some(item => item.customerMessageId === msg.customerMessageId) && 
          this.messageList.push(msg);
        this.scrollToBottom();
      };
      this.socket.onclose = () => {
        this.socketConnected = false;
        this.$message.warning("聊天连接已断开，正在重连...");
        this.reconnectWs();
      };
    },

    /** 3. WebSocket重连 */
    reconnectWs() {
      clearTimeout(this.reconnectTimer);
      this.reconnectTimer = setTimeout(() => {
        this.initWs();
      }, 3000);
    },

    /** 4. 加载历史消息：拦截器自动加Token */
    loadHistoryMsg() {
      if (!this.sessionId) return;
      this.loading = true;
      request({
        url: "/chat/customer/list",
        params: { customerSessionId: this.sessionId, pageSize: 50 } // 只传业务参数
      }).then(res => {
        this.loading = false;
        if (res.code === 200) {
          this.messageList = res.rows || [];
          this.scrollToBottom();
        }
      });
    },

    /** 5. 发送文本消息 */
    sendMsg() {
      const content = this.messageContent.trim();
      if (!content || !this.socketConnected) return;

      const msg = {
        customerSessionId: this.sessionId,
        customerMessageSenderId: this.$store.getters.userId,
        customerMessageSenderType: 3,
        customerMessageReceiverId: this.userId,
        customerMessageReceiverType: 2,
        customerMessageType: 1,
        customerMessageContent: content
      };

      this.socket.send(JSON.stringify(msg));
      // 本地渲染
      this.messageList.push({
        ...msg,
        customerMessageCreateTime: Date.now(),
        customerMessageId: `cs_${Date.now()}`
      });
      this.messageContent = "";
      this.scrollToBottom();
    },

    /** 6. 图片上传：拦截器自动加Token */
    handleImageUpload(res) {
      if (res.code === 200) {
        const msg = {
          customerSessionId: this.sessionId,
          customerMessageSenderId: this.$store.getters.userId,
          customerMessageSenderType: 3,
          customerMessageReceiverId: this.userId,
          customerMessageReceiverType: 2,
          customerMessageType: 2,
          customerMessageImageUrl: res.data
        };
        this.socket.send(JSON.stringify(msg));
        this.messageList.push({
          ...msg,
          customerMessageCreateTime: Date.now(),
          customerMessageId: `img_${Date.now()}`
        });
        this.scrollToBottom();
      } else {
        this.$message.error("图片发送失败");
      }
    },

    /** 7. 结束会话：拦截器自动加Token */
    handleEndSession() {
      this.$confirm("确定结束会话？", "提示", { type: "warning" }).then(() => {
        request({
          url: "/chat/session/end",
          method: "post",
          data: { sessionId: this.sessionId } // 只传业务参数
        }).then(res => {
          if (res.code === 200) {
            this.$message.success("会话已结束");
            this.sessionStatus = 1;
            this.socket?.close();
          }
        });
      });
    },

    /** 8. 滚动到底部 */
    scrollToBottom() {
      this.$nextTick(() => {
        const el = this.$refs.chatContentRef;
        el && (el.scrollTop = el.scrollHeight);
      });
    },

    /** 9. 格式化时间 */
    formatTime(time) {
      return time ? parseTime(time).slice(11, 19) : "";
    }
  }
};
</script>

<style scoped>


.app-container {
  padding: 15px;
  height: 100vh;
  box-sizing: border-box;
  background: #f5f5f5;
}

.chat-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
}

.session-status {
  font-size: 12px;
  color: #666;
  margin-bottom: 10px;
  padding: 5px 0;
  border-bottom: 1px solid #eee;
}
.split {
  margin: 0 5px;
  color: #ccc;
}

.chat-content {
  height: calc(100vh - 180px);
  overflow-y: auto;
  background: #fff;
  border: 1px solid #eee;
  border-radius: 4px;
  padding: 15px;
  margin-bottom: 10px;
}

.empty-tip {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 200px;
  color: #999;
}
.empty-tip i {
  font-size: 40px;
  margin-bottom: 10px;
}
.loading-tip {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100px;
  color: #666;
}
.loading-tip el-loading-spinner {
  margin-right: 8px;
}

.message-item {
  margin-bottom: 15px;
  display: flex;
}
.customer-msg {
  flex-direction: row;
}
.user-msg {
  flex-direction: row-reverse;
}
.msg-bubble {
  max-width: 70%;
  padding: 8px 12px;
  border-radius: 4px;
  margin: 0 8px;
}
.customer-bubble {
  background: #f5f7fa;
  border: 1px solid #eee;
}
.user-bubble {
  background: #409eff;
  color: #fff;
}
.msg-image {
  max-width: 100%;
  border-radius: 4px;
}
.msg-time {
  font-size: 10px;
  color: #999;
  display: block;
  text-align: right;
  margin-top: 5px;
}
.user-bubble .msg-time {
  color: rgba(255,255,255,0.7);
}

.chat-footer {
  display: flex;
  align-items: center;
  gap: 8px;
}
.upload-btn {
  white-space: nowrap;
}
</style>